/******************************************************************************
Copyright (c) 2013-2014, Altera Corporation.  All rights reserved.

Redistribution and use of this software, in source and binary code forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of Altera Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT HOLDERS OR CONTRIBUTORS ARE ADVISED OF THE POSSIBILITY DAMAGE IS LIKELY TO OCCUR.
******************************************************************************/
#include <core.h>
#include <trustzone.h>
#include <scu.h>
#include <alt_interrupt.h>
#include "socal/alt_sdr.h"

#define ALT_MPUSCU_NSAC_OFFSET            0x54
#define ALT_MPUSCU_NSAC_GLOBAL_NONSECURE  0xF00
#define ALT_MPUSCU_NSAC_PRIVATE_NONSECURE 0x0F0

#define ALT_SDR_CTL_OFST                      0x5000
#define ALT_SDR_CTL_PROTRULEID_LOW(x)         (x)
#define ALT_SDR_CTL_PROTRULEID_HIGH(x)        ((x) << 12)
#define ALT_SDR_CTL_PROTRULEADDR_LOW(x)       ((x) >> 20)
#define ALT_SDR_CTL_PROTRULEADDR_HIGH(x)      (((x)-1)>>8) & (0xFFF << 12)
#define ALT_SDR_CTL_DATA_RULE_VALID           (1<<2)
#define ALT_SDR_CTL_DATA_RULE_INVALID         0
#define ALT_L3_SEC_OFST                       8

uint32 ruleInUse[MAX_RULE_NUM] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

/**********************************************************************
    alt_sdr_ctl_set_tz_rule - add a new SDRam Access Rule
        uint32 RuleNum - ID of Rule that you want to override,
            use ALT_SDR_CTL_RULE_NEW if you want a new rule
        uint32 LowAddr - The lower bound of the memory this rule applies to
        uint32 HighAddr - The upper bound of the memory this rule applies to
        uint32 RuleMin - The lower ID of the peripherals this rule applies to
        uint32 RuleMax - The highest ID of the peripherals this rule applies to
        uint32 SecurityType -
            ALT_SDR_CTL_DATA_ACCESS_SECURE
            ALT_SDR_CTL_DATA_ACCESS_NONSECURE
            ALT_SDR_CTL_DATA_ACCESS_BOTH
        uint32 Ports - The ORing together of the PORTs that this rule applies to
        uint32 AccessPermission -
            ALT_SDR_CTL_DATA_DENY_ACCESS
            ALT_SDR_CTL_DATA_ALLOW_ACCESS

**********************************************************************/

uint32  alt_sdr_ctl_set_tz_rule(uint32 RuleNum, uint32 LowAddr, uint32 HighAddr, uint32 RuleMin, uint32 RuleMax,
    uint32 SecurityType, uint32 Ports, uint32 AccessPermission)
{
  volatile ALT_SDR_CTL_raw_t *sdr = (ALT_SDR_CTL_raw_t *)(ALT_SDR_OFST + ALT_SDR_CTL_OFST);
  if(RuleNum == ALT_SDR_CTL_RULE_NEW)
  {
    for(RuleNum=0; RuleNum<MAX_RULE_NUM; RuleNum++)
      if(ruleInUse[RuleNum] == 0)
        break;
    if(MAX_RULE_NUM == RuleNum)
      return   ALT_SDR_CTL_RULE_INVALID;
  }
  ruleInUse[RuleNum] = 1;
  sdr->protrulerdwr = ALT_SDR_CTL_PROTRULERDWR_RULEOFFSET_SET(RuleNum);
  sdr->protruleaddr = ALT_SDR_CTL_PROTRULEADDR_LOW(LowAddr) | ALT_SDR_CTL_PROTRULEADDR_HIGH(HighAddr);
  sdr->protruleid = ALT_SDR_CTL_PROTRULEID_LOW(RuleMin) | ALT_SDR_CTL_PROTRULEID_HIGH(RuleMax);
  sdr->protruledata = SecurityType | ALT_SDR_CTL_DATA_RULE_VALID | Ports | AccessPermission;
  sdr->protrulerdwr = ALT_SDR_CTL_PROTRULERDWR_RULEOFFSET_SET(RuleNum) | ALT_SDR_CTL_PROTRULERDWR_WRITE;
  sdr->protrulerdwr = ALT_SDR_CTL_PROTRULERDWR_RULEOFFSET_SET(RuleNum);
  return RuleNum;
}

/**********************************************************************
    alt_sdr_ctl_delete_rule - deletes a Trustzone SDRam Access Rule
        uint32 RuleNum - The Rule ID that was returned from set_tz_rule
**********************************************************************/

void    alt_sdr_ctl_delete_rule(uint32 RuleNum)
{
  volatile ALT_SDR_CTL_raw_t *sdr = (ALT_SDR_CTL_raw_t *)(ALT_SDR_OFST + ALT_SDR_CTL_OFST);
  sdr->protrulerdwr = ALT_SDR_CTL_PROTRULERDWR_RULEOFFSET_SET(RuleNum);
  sdr->protruledata = ALT_SDR_CTL_DATA_RULE_INVALID;
  sdr->protrulerdwr = ALT_SDR_CTL_PROTRULERDWR_RULEOFFSET_SET(RuleNum) | ALT_SDR_CTL_PROTRULERDWR_WRITE;
  sdr->protrulerdwr = ALT_SDR_CTL_PROTRULERDWR_RULEOFFSET_SET(RuleNum);
}

/**********************************************************************
    alt_sdr_ctl_set_tz_default - Set the global default for all memory
        that isn't specified in a specific Rule.

        uint32 defaultRule - One of the ALT_SDR_CTL_PROTPORT_DENY_ values
**********************************************************************/

uint32  alt_sdr_ctl_set_tz_default(uint32 defaultRule)
{
  volatile ALT_SDR_CTL_raw_t *sdr = (ALT_SDR_CTL_raw_t *)(ALT_SDR_OFST + ALT_SDR_CTL_OFST);
  sdr->protportdefault = defaultRule;
  return 0;
}

#define INVERSE(x) (0xFFFFFFFF ^ (x))
struct peripheral_ints
{
        uint64  peripheral;
        uint32  interrupt;
};

static struct peripheral_ints mapping[] = {
{ALT_L3_PERIPHERAL_GLOBALTIMER  , 27},
{ALT_L3_PERIPHERAL_LEGACY_FIQ   , 28},
{ALT_L3_PERIPHERAL_PRIVATETIMER , 29},
{ALT_L3_PERIPHERAL_LEGACY_NIRQ  , 31},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 32},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 33},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 34},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 35},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 36},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 37},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 38},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 39},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 40},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 41},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 42},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 43},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 44},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 45},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 46},
{ALT_L3_PERIPHERAL_PARITYFAIL_0 , 47},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 48},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 49},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 50},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 51},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 52},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 53},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 54},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 55},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 56},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 57},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 58},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 59},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 60},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 61},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 62},
{ALT_L3_PERIPHERAL_PARITYFAIL_1 , 63},
{ALT_L3_PERIPHERAL_PARITYFAIL_SCU, 64},
{ALT_L3_PERIPHERAL_PARITYFAIL_SCU, 65},
{ALT_L3_PERIPHERAL_PARITYFAIL_SCU, 66},
{ALT_L3_PERIPHERAL_L2_ECC_ERR   , 67},
{ALT_L3_PERIPHERAL_L2_ECC_ERR   , 68},
{ALT_L3_PERIPHERAL_L2_ECC_ERR   , 69},
{ALT_L3_PERIPHERAL_L2_ECC_ERR   , 70},
{ALT_L3_PERIPHERAL_DDR_ECC_ERR  , 71},
{ALT_L3_PERIPHERAL_FPGA         , 72},
{ALT_L3_PERIPHERAL_FPGA         , 73},
{ALT_L3_PERIPHERAL_FPGA         , 74},
{ALT_L3_PERIPHERAL_FPGA         , 75},
{ALT_L3_PERIPHERAL_FPGA         , 76},
{ALT_L3_PERIPHERAL_FPGA         , 77},
{ALT_L3_PERIPHERAL_FPGA         , 78},
{ALT_L3_PERIPHERAL_FPGA         , 79},
{ALT_L3_PERIPHERAL_FPGA         , 80},
{ALT_L3_PERIPHERAL_FPGA         , 81},
{ALT_L3_PERIPHERAL_FPGA         , 82},
{ALT_L3_PERIPHERAL_FPGA         , 83},
{ALT_L3_PERIPHERAL_FPGA         , 84},
{ALT_L3_PERIPHERAL_FPGA         , 85},
{ALT_L3_PERIPHERAL_FPGA         , 86},
{ALT_L3_PERIPHERAL_FPGA         , 87},
{ALT_L3_PERIPHERAL_FPGA         , 88},
{ALT_L3_PERIPHERAL_FPGA         , 89},
{ALT_L3_PERIPHERAL_FPGA         , 90},
{ALT_L3_PERIPHERAL_FPGA         , 91},
{ALT_L3_PERIPHERAL_FPGA         , 92},
{ALT_L3_PERIPHERAL_FPGA         , 93},
{ALT_L3_PERIPHERAL_FPGA         , 94},
{ALT_L3_PERIPHERAL_FPGA         , 95},
{ALT_L3_PERIPHERAL_FPGA         , 96},
{ALT_L3_PERIPHERAL_FPGA         , 97},
{ALT_L3_PERIPHERAL_FPGA         , 98},
{ALT_L3_PERIPHERAL_FPGA         , 99},
{ALT_L3_PERIPHERAL_FPGA         , 100},
{ALT_L3_PERIPHERAL_FPGA         , 101},
{ALT_L3_PERIPHERAL_FPGA         , 102},
{ALT_L3_PERIPHERAL_FPGA         , 103},
{ALT_L3_PERIPHERAL_FPGA         , 104},
{ALT_L3_PERIPHERAL_FPGA         , 105},
{ALT_L3_PERIPHERAL_FPGA         , 106},
{ALT_L3_PERIPHERAL_FPGA         , 107},
{ALT_L3_PERIPHERAL_FPGA         , 108},
{ALT_L3_PERIPHERAL_FPGA         , 109},
{ALT_L3_PERIPHERAL_FPGA         , 110},
{ALT_L3_PERIPHERAL_FPGA         , 111},
{ALT_L3_PERIPHERAL_FPGA         , 112},
{ALT_L3_PERIPHERAL_FPGA         , 113},
{ALT_L3_PERIPHERAL_FPGA         , 114},
{ALT_L3_PERIPHERAL_FPGA         , 115},
{ALT_L3_PERIPHERAL_FPGA         , 116},
{ALT_L3_PERIPHERAL_FPGA         , 117},
{ALT_L3_PERIPHERAL_FPGA         , 118},
{ALT_L3_PERIPHERAL_FPGA         , 119},
{ALT_L3_PERIPHERAL_FPGA         , 120},
{ALT_L3_PERIPHERAL_FPGA         , 121},
{ALT_L3_PERIPHERAL_FPGA         , 122},
{ALT_L3_PERIPHERAL_FPGA         , 123},
{ALT_L3_PERIPHERAL_FPGA         , 124},
{ALT_L3_PERIPHERAL_FPGA         , 125},
{ALT_L3_PERIPHERAL_FPGA         , 126},
{ALT_L3_PERIPHERAL_FPGA         , 127},
{ALT_L3_PERIPHERAL_FPGA         , 128},
{ALT_L3_PERIPHERAL_FPGA         , 129},
{ALT_L3_PERIPHERAL_FPGA         , 130},
{ALT_L3_PERIPHERAL_FPGA         , 131},
{ALT_L3_PERIPHERAL_FPGA         , 132},
{ALT_L3_PERIPHERAL_FPGA         , 133},
{ALT_L3_PERIPHERAL_FPGA         , 134},
{ALT_L3_PERIPHERAL_FPGA         , 135},
{ALT_L3_PERIPHERAL_DMA          , 136},
{ALT_L3_PERIPHERAL_DMA          , 137},
{ALT_L3_PERIPHERAL_DMA          , 138},
{ALT_L3_PERIPHERAL_DMA          , 139},
{ALT_L3_PERIPHERAL_DMA          , 140},
{ALT_L3_PERIPHERAL_DMA          , 141},
{ALT_L3_PERIPHERAL_DMA          , 142},
{ALT_L3_PERIPHERAL_DMA          , 143},
{ALT_L3_PERIPHERAL_DMA          , 144},
{ALT_L3_PERIPHERAL_DMA          , 145},
{ALT_L3_PERIPHERAL_DMA          , 146},
{ALT_L3_PERIPHERAL_EMAC0        , 147},
{ALT_L3_PERIPHERAL_EMAC0        , 148},
{ALT_L3_PERIPHERAL_EMAC0        , 149},
{ALT_L3_PERIPHERAL_EMAC0        , 150},
{ALT_L3_PERIPHERAL_EMAC0        , 151},
{ALT_L3_PERIPHERAL_EMAC1        , 152},
{ALT_L3_PERIPHERAL_EMAC1        , 153},
{ALT_L3_PERIPHERAL_EMAC1        , 154},
{ALT_L3_PERIPHERAL_EMAC1        , 155},
{ALT_L3_PERIPHERAL_EMAC1        , 156},
{ALT_L3_PERIPHERAL_USB0         , 157},
{ALT_L3_PERIPHERAL_USB0         , 158},
{ALT_L3_PERIPHERAL_USB0         , 159},
{ALT_L3_PERIPHERAL_USB1         , 160},
{ALT_L3_PERIPHERAL_USB1         , 161},
{ALT_L3_PERIPHERAL_USB1         , 162},
{ALT_L3_PERIPHERAL_CAN0         , 163},
{ALT_L3_PERIPHERAL_CAN0         , 164},
{ALT_L3_PERIPHERAL_CAN0         , 165},
{ALT_L3_PERIPHERAL_CAN0         , 166},
{ALT_L3_PERIPHERAL_CAN1         , 167},
{ALT_L3_PERIPHERAL_CAN1         , 168},
{ALT_L3_PERIPHERAL_CAN1         , 169},
{ALT_L3_PERIPHERAL_CAN1         , 170},
{ALT_L3_PERIPHERAL_SDMMC        , 171},
{ALT_L3_PERIPHERAL_SDMMC        , 172},
{ALT_L3_PERIPHERAL_SDMMC        , 173},
{ALT_L3_PERIPHERAL_SDMMC        , 174},
{ALT_L3_PERIPHERAL_SDMMC        , 175},
{ALT_L3_PERIPHERAL_NAND         , 176},
{ALT_L3_PERIPHERAL_NAND         , 177},
{ALT_L3_PERIPHERAL_NAND         , 178},
{ALT_L3_PERIPHERAL_NAND         , 179},
{ALT_L3_PERIPHERAL_NAND         , 180},
{ALT_L3_PERIPHERAL_NAND         , 181},
{ALT_L3_PERIPHERAL_NAND         , 182},
{ALT_L3_PERIPHERAL_QSPI         , 183},
{ALT_L3_PERIPHERAL_QSPI         , 184},
{ALT_L3_PERIPHERAL_QSPI         , 185},
{ALT_L3_PERIPHERAL_SPI0_SLAVE   , 186},
{ALT_L3_PERIPHERAL_SPI1_SLAVE   , 187},
{ALT_L3_PERIPHERAL_SPI0_MASTER  , 188},
{ALT_L3_PERIPHERAL_SPI1_MASTER  , 189},
{ALT_L3_PERIPHERAL_I2C0         , 190},
{ALT_L3_PERIPHERAL_I2C1         , 191},
{ALT_L3_PERIPHERAL_I2C2         , 192},
{ALT_L3_PERIPHERAL_I2C3         , 193},
{ALT_L3_PERIPHERAL_UART0        , 194},
{ALT_L3_PERIPHERAL_UART1        , 195},
{ALT_L3_PERIPHERAL_GPIO0        , 196},
{ALT_L3_PERIPHERAL_GPIO1        , 197},
{ALT_L3_PERIPHERAL_GPIO2        , 198},
{ALT_L3_PERIPHERAL_SPTIMER0     , 199},
{ALT_L3_PERIPHERAL_SPTIMER1     , 200},
{ALT_L3_PERIPHERAL_OSCTIMER0    , 201},
{ALT_L3_PERIPHERAL_OSCTIMER1    , 202},
{ALT_L3_PERIPHERAL_WATCHDOG0    , 203},
{ALT_L3_PERIPHERAL_WATCHDOG1    , 204},
{ALT_L3_PERIPHERAL_CLKMGR       , 205},
{ALT_L3_PERIPHERAL_MPUWAKEUP    , 206},
{ALT_L3_PERIPHERAL_FPGAMNGR     , 207},
{ALT_L3_PERIPHERAL_CORESIGHT    , 208},
{ALT_L3_PERIPHERAL_CORESIGHT    , 209},
{ALT_L3_PERIPHERAL_OCR          , 210},
{ALT_L3_PERIPHERAL_OCR          , 211}
};

void alt_int_dist_target_set_for_device(uint64 Devices, alt_int_cpu_target_t target)
{
  uint32 mapnum;
  for(mapnum=0; mapnum < sizeof(mapping)/sizeof(mapping[0]); mapnum++)
  {
    if(mapping[mapnum].peripheral & Devices)
    {
      alt_int_dist_target_set((ALT_INT_INTERRUPT_t)mapping[mapnum].interrupt, target);
    }
  }
}

void alt_l3_secgrp_set_peripheral_access(uint64 NonSecure, uint64 SecureOnly)
{
  volatile ALT_L3_SECGRP_raw_t *l3s = (ALT_L3_SECGRP_raw_t *) (ALT_L3_OFST + ALT_L3_SEC_OFST);
  volatile uint32 *scu_ns_p = (uint32 *) ((uint32) ALT_MPUSCU_ADDR + ALT_MPUSCU_NSAC_OFFSET);

  uint32 main, main_o, l4sp, l4sp_o, l4mp, l4mp_o, l4osc1, l4osc1_o, l4spim, l4spim_o, scu_ns, scu_ns_o;
  uint32 mapnum;

  main_o = main = l3s->l4main;
  l4sp_o = l4sp = l3s->l4sp;
  l4mp_o = l4mp = l3s->l4mp;
  l4osc1_o = l4osc1 = l3s->l4osc1;
  l4spim_o = l4spim = l3s->l4spim;
  scu_ns_o = scu_ns = *scu_ns_p;

  for(mapnum=0; mapnum < sizeof(mapping)/sizeof(mapping[0]); mapnum++)
  {
    if(mapping[mapnum].peripheral & NonSecure)
    {
      alt_int_dist_secure_disable((ALT_INT_INTERRUPT_t)mapping[mapnum].interrupt);
    }
    if(mapping[mapnum].peripheral & SecureOnly)
    {
      alt_int_dist_secure_enable((ALT_INT_INTERRUPT_t)mapping[mapnum].interrupt);
    }
  }

  //?? There is a secure and a nonsecure dma device. What's this peripheral about?
  if(NonSecure & ALT_L3_PERIPHERAL_DMA)
    main |= ALT_L3_SEC_L4MAIN_DMASECURE_SET(ALT_L3_SEC_L4MAIN_DMASECURE_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_DMA)
    main &= INVERSE(ALT_L3_SEC_L4MAIN_DMASECURE_SET(ALT_L3_SEC_L4MAIN_DMASECURE_E_NONSECURE));

  if(NonSecure & ALT_L3_PERIPHERAL_USB0)
    l3s->usb0 = ALT_L3_SEC_USB0_S_SET(ALT_L3_SEC_USB0_S_E_NONSECURE); 
  if(SecureOnly & ALT_L3_PERIPHERAL_USB0)
    l3s->usb0 = ALT_L3_SEC_USB0_S_SET(ALT_L3_SEC_USB0_S_E_SECURE); 

  if(NonSecure & ALT_L3_PERIPHERAL_USB1)
    l3s->usb1 = ALT_L3_SEC_USB1_S_SET(ALT_L3_SEC_USB1_S_E_NONSECURE); 
  if(SecureOnly & ALT_L3_PERIPHERAL_USB1)
    l3s->usb1 = ALT_L3_SEC_USB1_S_SET(ALT_L3_SEC_USB1_S_E_SECURE); 

  
  if(NonSecure & ALT_L3_PERIPHERAL_CAN0)
    l4sp |= ALT_L3_SEC_L4SP_CAN0_SET(ALT_L3_SEC_L4SP_CAN0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_CAN0)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_CAN0_SET(ALT_L3_SEC_L4SP_CAN0_E_NONSECURE));

  if(NonSecure & ALT_L3_PERIPHERAL_CAN1)
    l4sp |= ALT_L3_SEC_L4SP_CAN1_SET(ALT_L3_SEC_L4SP_CAN1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_CAN1)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_CAN1_SET(ALT_L3_SEC_L4SP_CAN1_E_NONSECURE));

  if(NonSecure & ALT_L3_PERIPHERAL_SDMMC)
    l4mp |= ALT_L3_SEC_L4MP_SDMMC_SET(ALT_L3_SEC_L4MP_SDMMC_E_NONSECURE); 
  if(SecureOnly & ALT_L3_PERIPHERAL_SDMMC)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_SDMMC_SET(ALT_L3_SEC_L4MP_SDMMC_E_NONSECURE));

  if(NonSecure & ALT_L3_PERIPHERAL_NAND)
  {
    l3s->nanddata = ALT_L3_SEC_NANDDATA_S_SET(ALT_L3_SEC_NANDDATA_S_E_NONSECURE);
    l3s->nandregs = ALT_L3_SEC_NAND_S_SET(ALT_L3_SEC_NAND_S_E_NONSECURE);
  }
  if(SecureOnly & ALT_L3_PERIPHERAL_NAND)
  {
    l3s->nanddata = ALT_L3_SEC_NANDDATA_S_SET(ALT_L3_SEC_NANDDATA_S_E_SECURE);
    l3s->nandregs = ALT_L3_SEC_NAND_S_SET(ALT_L3_SEC_NAND_S_E_SECURE);
  }

  if(NonSecure & ALT_L3_PERIPHERAL_QSPI)
  {
    l3s->qspidata = ALT_L3_SEC_QSPIDATA_S_SET(ALT_L3_SEC_QSPIDATA_S_E_NONSECURE);
    l4mp |= ALT_L3_SEC_L4MP_QSPI_SET(ALT_L3_SEC_L4MP_QSPI_E_NONSECURE);
  }
  if(SecureOnly & ALT_L3_PERIPHERAL_QSPI)
  {
    l3s->qspidata = ALT_L3_SEC_QSPIDATA_S_SET(ALT_L3_SEC_QSPIDATA_S_E_SECURE);
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_QSPI_SET(ALT_L3_SEC_L4MP_QSPI_E_NONSECURE));
  }

  if(NonSecure & ALT_L3_PERIPHERAL_SPI0_SLAVE)
    l4spim |= ALT_L3_SEC_L4SPIM_SPIM0_SET(ALT_L3_SEC_L4SPIM_SPIM0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SPI0_SLAVE)
    l4spim &= INVERSE(ALT_L3_SEC_L4SPIM_SPIM0_SET(ALT_L3_SEC_L4SPIM_SPIM0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_SPI1_SLAVE)
    l4spim |= ALT_L3_SEC_L4SPIM_SPIM1_SET(ALT_L3_SEC_L4SPIM_SPIM1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SPI1_SLAVE)
    l4spim &= INVERSE(ALT_L3_SEC_L4SPIM_SPIM1_SET(ALT_L3_SEC_L4SPIM_SPIM1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_SPI0_MASTER)
    main |= ALT_L3_SEC_L4MAIN_SPIS0_SET(ALT_L3_SEC_L4MAIN_SPIS0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SPI0_MASTER)
    main &= INVERSE(ALT_L3_SEC_L4MAIN_SPIS0_SET(ALT_L3_SEC_L4MAIN_SPIS0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_SPI1_MASTER)
    main |= ALT_L3_SEC_L4MAIN_SPIS1_SET(ALT_L3_SEC_L4MAIN_SPIS1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SPI1_MASTER)
    main &= INVERSE(ALT_L3_SEC_L4MAIN_SPIS1_SET(ALT_L3_SEC_L4MAIN_SPIS1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_I2C0)
    l4sp |= ALT_L3_SEC_L4SP_I2C0_SET(ALT_L3_SEC_L4SP_I2C0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_I2C0)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_I2C0_SET(ALT_L3_SEC_L4SP_I2C0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_I2C1)
    l4sp |= ALT_L3_SEC_L4SP_I2C1_SET(ALT_L3_SEC_L4SP_I2C1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_I2C1)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_I2C1_SET(ALT_L3_SEC_L4SP_I2C1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_I2C2)
    l4sp |= ALT_L3_SEC_L4SP_I2C2_SET(ALT_L3_SEC_L4SP_I2C2_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_I2C2)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_I2C2_SET(ALT_L3_SEC_L4SP_I2C2_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_I2C3)
    l4sp |= ALT_L3_SEC_L4SP_I2C3_SET(ALT_L3_SEC_L4SP_I2C3_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_I2C3)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_I2C3_SET(ALT_L3_SEC_L4SP_I2C3_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_EMAC0)
    l4mp |= ALT_L3_SEC_L4MP_EMAC0_SET(ALT_L3_SEC_L4MP_EMAC0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_EMAC0)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_EMAC0_SET(ALT_L3_SEC_L4MP_EMAC0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_EMAC1)
    l4mp |= ALT_L3_SEC_L4MP_EMAC1_SET(ALT_L3_SEC_L4MP_EMAC1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_EMAC1)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_EMAC1_SET(ALT_L3_SEC_L4MP_EMAC1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_UART0)
    l4sp |= ALT_L3_SEC_L4SP_UART0_SET(ALT_L3_SEC_L4SP_UART0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_UART0)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_UART0_SET(ALT_L3_SEC_L4SP_UART0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_UART1)
    l4sp |= ALT_L3_SEC_L4SP_UART1_SET(ALT_L3_SEC_L4SP_UART1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_UART1)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_UART1_SET(ALT_L3_SEC_L4SP_UART1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_GPIO0)
    l4mp |= ALT_L3_SEC_L4MP_GPIO0_SET(ALT_L3_SEC_L4MP_GPIO0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_GPIO0)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_GPIO0_SET(ALT_L3_SEC_L4MP_GPIO0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_GPIO1)
    l4mp |= ALT_L3_SEC_L4MP_GPIO1_SET(ALT_L3_SEC_L4MP_GPIO1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_GPIO1)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_GPIO1_SET(ALT_L3_SEC_L4MP_GPIO1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_GPIO2)
    l4mp |= ALT_L3_SEC_L4MP_GPIO2_SET(ALT_L3_SEC_L4MP_GPIO2_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_GPIO2)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_GPIO2_SET(ALT_L3_SEC_L4MP_GPIO2_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_SPTIMER0)
    l4sp |= ALT_L3_SEC_L4SP_SPTMR0_SET(ALT_L3_SEC_L4SP_SPTMR0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SPTIMER0)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_SPTMR0_SET(ALT_L3_SEC_L4SP_SPTMR0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_SPTIMER1)
    l4sp |= ALT_L3_SEC_L4SP_SPTMR1_SET(ALT_L3_SEC_L4SP_SPTMR1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SPTIMER1)
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_SPTMR1_SET(ALT_L3_SEC_L4SP_SPTMR1_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_OSCTIMER0)
    l4osc1 |= ALT_L3_SEC_L4OSC1_OSC1TMR0_SET(ALT_L3_SEC_L4OSC1_OSC1TMR0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_OSCTIMER1)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_OSC1TMR0_SET(ALT_L3_SEC_L4OSC1_OSC1TMR0_E_NONSECURE));
  
  if(NonSecure & ALT_L3_PERIPHERAL_OSCTIMER1)
    l4osc1 |= ALT_L3_SEC_L4OSC1_OSC1TMR0_SET(ALT_L3_SEC_L4OSC1_OSC1TMR1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_OSCTIMER1)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_OSC1TMR0_SET(ALT_L3_SEC_L4OSC1_OSC1TMR1_E_NONSECURE));

  if(NonSecure & ALT_L3_PERIPHERAL_WATCHDOG0)
    l4osc1 |= ALT_L3_SEC_L4OSC1_L4WD0_SET(ALT_L3_SEC_L4OSC1_L4WD0_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_WATCHDOG0)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_L4WD0_SET(ALT_L3_SEC_L4OSC1_L4WD0_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_WATCHDOG1)
    l4osc1 |= ALT_L3_SEC_L4OSC1_L4WD1_SET(ALT_L3_SEC_L4OSC1_L4WD1_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_WATCHDOG1)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_L4WD1_SET(ALT_L3_SEC_L4OSC1_L4WD1_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_CLKMGR)
    l4osc1 |= ALT_L3_SEC_L4OSC1_CLKMGR_SET(ALT_L3_SEC_L4OSC1_CLKMGR_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_CLKMGR)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_CLKMGR_SET(ALT_L3_SEC_L4OSC1_CLKMGR_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_OCR)
     l3s->ocram = ALT_L3_SEC_OCRAM_S_SET(ALT_L3_SEC_OCRAM_S_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_OCR)
     l3s->ocram = ALT_L3_SEC_OCRAM_S_SET(ALT_L3_SEC_OCRAM_S_E_SECURE);
 
  if(NonSecure & ALT_L3_PERIPHERAL_ACP)
  {
    l3s->acp = ALT_L3_SEC_ACP_S_SET(ALT_L3_SEC_ACP_S_E_NONSECURE);
    l4mp |= ALT_L3_SEC_L4MP_ACPIDMAP_SET(ALT_L3_SEC_L4MP_ACPIDMAP_E_NONSECURE);
  }
  if(SecureOnly & ALT_L3_PERIPHERAL_ACP)
  {
    l3s->acp = ALT_L3_SEC_ACP_S_SET(ALT_L3_SEC_ACP_S_E_SECURE);
    l4mp &= INVERSE((ALT_L3_SEC_L4MP_ACPIDMAP_SET(ALT_L3_SEC_L4MP_ACPIDMAP_E_NONSECURE)));
  }
 
  if(NonSecure & ALT_L3_PERIPHERAL_ROM)
      l3s->rom = ALT_L3_SEC_ROM_S_SET(ALT_L3_SEC_ROM_S_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_ROM)
      l3s->rom = ALT_L3_SEC_ROM_S_SET(ALT_L3_SEC_ROM_S_E_SECURE);
 
  if(NonSecure & ALT_L3_PERIPHERAL_SDRAMCTRL)
  {
    l3s->sdrdata = ALT_L3_SEC_SDRDATA_S_SET(ALT_L3_SEC_SDRDATA_S_E_NONSECURE);
    l4sp |= ALT_L3_SEC_L4SP_SDRREGS_SET(ALT_L3_SEC_L4SP_SDRREGS_E_NONSECURE);
  }
  if(SecureOnly & ALT_L3_PERIPHERAL_SDRAMCTRL)
  {
    l3s->sdrdata = ALT_L3_SEC_SDRDATA_S_SET(ALT_L3_SEC_SDRDATA_S_E_SECURE);
    l4sp &= INVERSE(ALT_L3_SEC_L4SP_SDRREGS_SET(ALT_L3_SEC_L4SP_SDRREGS_E_NONSECURE));
  }
 
  if(NonSecure & ALT_L3_PERIPHERAL_DAP)
    l4mp |= ALT_L3_SEC_L4MP_DAP_SET(ALT_L3_SEC_L4MP_DAP_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_DAP)
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_DAP_SET(ALT_L3_SEC_L4MP_DAP_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_RESET)
    l4osc1 |= ALT_L3_SEC_L4OSC1_RSTMGR_SET(ALT_L3_SEC_L4OSC1_RSTMGR_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_RESET)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_RSTMGR_SET(ALT_L3_SEC_L4OSC1_RSTMGR_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_SYSMGR)
    l4osc1 |= ALT_L3_SEC_L4OSC1_SYSMGR_SET(ALT_L3_SEC_L4OSC1_SYSMGR_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SYSMGR)
    l4osc1 &= INVERSE(ALT_L3_SEC_L4OSC1_SYSMGR_SET(ALT_L3_SEC_L4OSC1_SYSMGR_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_SCANMGR)
    l4spim |= ALT_L3_SEC_L4SPIM_SCANMGR_SET(ALT_L3_SEC_L4SPIM_SCANMGR_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_SCANMGR)
    l4spim &= INVERSE(ALT_L3_SEC_L4SPIM_SCANMGR_SET(ALT_L3_SEC_L4SPIM_SCANMGR_E_NONSECURE));
 
  if(NonSecure & ALT_L3_PERIPHERAL_STMSLAVE)
    l3s->stm = ALT_L3_SEC_STM_S_SET(ALT_L3_SEC_STM_S_E_NONSECURE);
  if(SecureOnly & ALT_L3_PERIPHERAL_STMSLAVE)
    l3s->stm = ALT_L3_SEC_STM_S_SET(ALT_L3_SEC_STM_S_E_SECURE);
 
  if(NonSecure & ALT_L3_PERIPHERAL_FPGA)
  {
    l3s->hps2fpgaregs = ALT_L3_SEC_H2F_S_SET(ALT_L3_SEC_H2F_S_E_NONSECURE);
    l3s->lwhps2fpgaregs = ALT_L3_SEC_LWH2F_S_SET(ALT_L3_SEC_LWH2F_S_E_NONSECURE);
  }
  if(SecureOnly & ALT_L3_PERIPHERAL_FPGA)
  {
    l3s->hps2fpgaregs = ALT_L3_SEC_H2F_S_SET(ALT_L3_SEC_H2F_S_E_SECURE);
    l3s->lwhps2fpgaregs = ALT_L3_SEC_LWH2F_S_SET(ALT_L3_SEC_LWH2F_S_E_SECURE);
  }
 
  if(NonSecure & ALT_L3_PERIPHERAL_FPGAMNGR)
  {
    l3s->fpgamgrdata = ALT_L3_SEC_FPGAMGRDATA_S_SET(ALT_L3_SEC_FPGAMGRDATA_S_E_NONSECURE);
    l4mp |= ALT_L3_SEC_L4MP_FPGAMGR_SET(ALT_L3_SEC_L4MP_FPGAMGR_E_NONSECURE);
  }
  if(SecureOnly & ALT_L3_PERIPHERAL_FPGAMNGR)
  {
    l3s->fpgamgrdata = ALT_L3_SEC_FPGAMGRDATA_S_SET(ALT_L3_SEC_FPGAMGRDATA_S_E_SECURE);
    l4mp &= INVERSE(ALT_L3_SEC_L4MP_FPGAMGR_SET(ALT_L3_SEC_L4MP_FPGAMGR_E_NONSECURE));
  }
 
  if(NonSecure & ALT_L3_PERIPHERAL_GLOBALTIMER)
     scu_ns |= ALT_MPUSCU_NSAC_GLOBAL_NONSECURE;
  if(SecureOnly & ALT_L3_PERIPHERAL_GLOBALTIMER)
     scu_ns &= INVERSE(ALT_MPUSCU_NSAC_GLOBAL_NONSECURE);
 
  if(NonSecure & ALT_L3_PERIPHERAL_PRIVATETIMER)
    scu_ns |= ALT_MPUSCU_NSAC_PRIVATE_NONSECURE;
  if(SecureOnly & ALT_L3_PERIPHERAL_PRIVATETIMER)
    scu_ns &= INVERSE(ALT_MPUSCU_NSAC_PRIVATE_NONSECURE);
 
  if(main_o != main )
    l3s->l4main = main;
  if(l4sp_o != l4sp)
    l3s->l4sp = l4sp;
  if(l4mp_o != l4mp)
    l3s->l4mp = l4mp;
  if(l4osc1_o != l4osc1)
    l3s->l4osc1 = l4osc1;
  if(l4spim_o != l4spim)
    l3s->l4spim = l4spim;
  if(scu_ns_o != scu_ns)
    *scu_ns_p = scu_ns;
}
